package com.zzyl.nursing.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.SecurityUtils;
import com.zzyl.nursing.domain.AlertData;
import com.zzyl.nursing.dto.AlertDataDto;
import com.zzyl.nursing.dto.AlertDataPageReqDto;
import com.zzyl.nursing.mapper.AlertDataMapper;
import com.zzyl.nursing.service.IAlertDataService;
import com.zzyl.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.Arrays;

/**
 * 报警数据Service业务层处理
 * 
 * @author mr.wu
 * @date 2025-05-29
 */
@Service
public class AlertDataServiceImpl extends ServiceImpl<AlertDataMapper, AlertData> implements IAlertDataService
{
    @Autowired
    private AlertDataMapper alertDataMapper;

    /**
     * 查询报警数据
     * 
     * @param id 报警数据主键
     * @return 报警数据
     */
    @Override
    public AlertData selectAlertDataById(Long id)
    {
        return getById(id);
    }

    @Autowired
    private ISysUserService sysUserService;

    @Value("${alertRule.roleAdmin}")
    private String roleAdmin;

    /**
     * 查询报警数据列表
     * @return 报警数据
     */
    @Override
    public Page selectAlertDataList(AlertDataPageReqDto dto)
    {
        String roleGroup = sysUserService.selectUserRoleGroup(SecurityUtils.getLoginUser().getUsername());

        Page<AlertData> page = this.lambdaQuery()
                //当前登录用户不是管理员，才只看自己负责的报警数据，不能看其他人员的
                .eq(!roleGroup.contains(roleAdmin), AlertData::getUserId, SecurityUtils.getUserId())
                .eq(dto.getStatus() != null, AlertData::getStatus, dto.getStatus())
                .like(StrUtil.isNotBlank(dto.getDeviceName()), AlertData::getDeviceName, dto.getDeviceName())
                .between(dto.getStartTime() != null && dto.getEndTime() != null, AlertData::getCreateTime, dto.getStartTime(), dto.getEndTime())
                .page(new Page<>(dto.getPageNum(), dto.getPageSize()));


        return page;
    }

    /**
     * 新增报警数据
     * 
     * @param alertData 报警数据
     * @return 结果
     */
    @Override
    public int insertAlertData(AlertData alertData)
    {
        return save(alertData) ? 1 : 0;
    }

    /**
     * 修改报警数据
     * 
     * @param alertData 报警数据
     * @return 结果
     */
    @Override
    public int updateAlertData(AlertData alertData)
    {
        return updateById(alertData) ? 1 : 0;
    }

    /**
     * 批量删除报警数据
     * 
     * @param ids 需要删除的报警数据主键
     * @return 结果
     */
    @Override
    public int deleteAlertDataByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除报警数据信息
     * 
     * @param id 报警数据主键
     * @return 结果
     */
    @Override
    public int deleteAlertDataById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 处理设备报警数据
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleAlertData(AlertDataDto dto) {
        //1.判断报警数据是否存在
        AlertData data = this.lambdaQuery().eq(AlertData::getId, dto.getId()).one();
        if(data==null) {
            throw new BaseException("报警数据不存在");
        }

        //2.判断是否处理过
        if(data.getStatus()==1) {
            throw new BaseException("已处理过");
        }

        //3.更新报警数据处理结果 （不要通过id更新，因为ID只能更新一条，而一次警告信息因为有多个护理人员会产生多条报警数据）-（其他负责这个设备的人也能看到更改结果）
        boolean result = this.lambdaUpdate()
                .eq(AlertData::getProductKey, data.getProductKey())
                .eq(AlertData::getDeviceName, data.getDeviceName())
                .eq(AlertData::getFunctionId, data.getFunctionId())
                .eq(AlertData::getAlertRuleId, data.getAlertRuleId())
                .eq(AlertData::getDataValue, data.getDataValue())
                .eq(AlertData::getCreateTime, data.getCreateTime())
                .eq(AlertData::getStatus, 0)//待处理
                .set(AlertData::getProcessorId,SecurityUtils.getUserId())
                .set(AlertData::getProcessorName,SecurityUtils.getUsername() )
                .set(AlertData::getProcessingResult, dto.getProcessingResult())
                .set(AlertData::getProcessingTime, OffsetDateTime.parse(dto.getProcessingTime()).atZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime())
                .set(AlertData::getStatus,1) //已处理
                .update();
        if(!result) {
            throw new BaseException("更新处理结果失败");
        }
    }
}
